-- loveme -- LOVE Mask Editor draws image masks of a specified font
--           and characters in order to make LOVE image font creation easier
--           This program is a part of inLOVE project.
-- Copyright (C) 2008 Miroslav Hradilek

-- This program is  free software:  you can redistribute it and/or modify it
-- under  the terms  of the  GNU General Public License  as published by the
-- Free Software Foundation, version 3 of the License.
--
-- This program  is  distributed  in the hope  that it will  be useful,  but
-- WITHOUT  ANY WARRANTY;  without  even the implied  warranty of MERCHANTA-
-- BILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-- License for more details.
--
-- You should have received a copy of the  GNU General Public License  along
-- with this program. If not, see <http://www.gnu.org/licenses/>.

-- set everything needed for the first start
function load()
    app_version = "0.9.5"                   -- version of the application
    error_value = ""                        -- declare for errors

  -- parse config
    getConfig()
    
  -- set variables
    lag = 100         -- ms delay between actions when holding key
    
    window_width  = love.graphics.getWidth()  -- width of the window
    window_height = love.graphics.getHeight() -- height of the window
    
    background_color  = love.graphics.newColor(128, 128, 128) -- 50% gray
    black             = love.graphics.newColor(  0,   0,   0) -- black
    white             = love.graphics.newColor(255, 255, 255) -- white
    
    transparent_color      = black
    transparent_color_info = "Black"                          -- hud info
    visible_color          = white
    visible_color_info     = "White"                          -- hud info
    
    border_color      = love.graphics.newColor(255, 0,   0)   -- red
    
    separator_color   = love.graphics.newColor(255, 255,   0) -- yellow
    separator_width   = 1                                     -- width of
                                                              -- letter
                                                              -- separators
    
    mask_font_path  = config.font       -- path to the font file
    mask_font_size  = config.font_size  -- font size
    mask_characters = config.glyphs     -- characters wanted in a font

    distance = 0                        -- necessary declaration
    
    hud_font_color  = love.graphics.newColor(  0, 255,   0)   -- lime green
    hud_bg_color    = love.graphics.newColor(  0,   0,   0, 128)    
    hud_x        = 0                   -- hud left upper corner x
    hud_y        = 0                   -- hud left upper corner y
    hud_width    = 250                 -- width of the hud
    hud_height   = window_height       -- height of the hud
    hud_space    = 100                 -- space between hud text and values
    show_hud     = config.show_help    -- show hud after start?

--    mask_x       = 2                   -- mask left upper corner x
    mask_x       = config.x            -- mask left upper corner x
--    mask_y       = 2                   -- mask left upper corner y
    mask_y       = config.y            -- mask left upper corner y
    mask_width   = 1                   -- width of the mask
    mask_height  = 1                   -- height of the mask
    
--    left_margin  = 0                   -- left margin of character
    left_margin  = config.left_margin  -- left margin of character
--    right_margin = 0                   -- right margin of character
    right_margin = config.right_margin -- right margin of character

    text_x       = mask_x              -- x position of mask text
    text_y       = mask_y              -- y position of mask text

  -- load resources
    hud_font     = love.graphics.newFont(love.default_font, 12)
    mask_font    = love.graphics.newFont(mask_font_path, mask_font_size)

  -- set resources
    love.graphics.setBackgroundColor(background_color) -- set background
    
    updateVariables()                  -- update dependent variables
end

-- fills table with key = value pairs from the config file
function getConfig()
  -- set variables
  file_name = "config.conf"
  
  -- create a file object
  file = love.filesystem.newFile(file_name)
  
  -- open file
  if love.filesystem.open(file) then
    -- read the whole config into a memory
    -- the stupidest thing ever but, easy I must admit
    config_content = love.filesystem.read(file)
    -- close file
    love.filesystem.close(file)
    
    config = {} -- declare table
    
    -- parse file content   
    for line in config_content:gfind("(.-)\n") do
    -- read line
      if not line:find("^%s*#") then
      -- line is not comment
        -- parse key = value pair
        _, _, key, value = line:find("%s*(.-)%s*=%s*\"?(.-)\"?%s*$")
        if key and value then
        -- key and value exist
          -- make true/false strings boolean
          if value == "true" then
            value = true
          elseif value == "false" then
            value = false
          else
            -- do nothing
            -- lua should recognize it
          end
          
          -- insert key and value to the table
          config[key] = value
        end
      end
    end
    
    -- set missing variables to default values
    config.font      = config.font      or love.default_font
    config.glyphs    = config.glyphs    or " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&`'*#=[]\""
    config.font_size = config.font_size or 12
    config.x         = config.x         or 2
    config.y         = config.y         or 2
    config.left_margin  = config.left_margin  or 0
    config.right_margin = config.right_margin or 0    
    if not ((config.show_help == false) or (config.show_help == true)) then
      config.show_help = true end
  else
    -- error
    error_value = "Error: Coldn't open the file \"" .. file_name .. "\""
  end
end

-- draws help screen
function drawHud()
  love.graphics.setColor(hud_bg_color)   -- set hud background color
  love.graphics.rectangle(love.draw_fill, hud_x, hud_y,
                          hud_width, hud_height) -- draw
  love.graphics.setColor(hud_font_color) -- set hud color
  love.graphics.setFont(hud_font)        -- set hud font
  love.graphics.draw(hud_text, hud_x + 5, hud_y + 1 + hud_font:getHeight())
                                         -- set hud text position and
                                         -- move y 0 to upper left corner
  love.graphics.draw(hud_values, hud_x + 5 + hud_space,
                     hud_y + 1 + hud_font:getHeight())
                                         -- set hud values text position and
                                         -- move y 0 to upper left corner
  love.graphics.draw("[LoveME " .. app_version .. "]", hud_x + 5,
                     hud_height - 6)
end

-- returns true if one of the keys is down
function areDown(key1, key2)
  return love.keyboard.isDown(key1) or love.keyboard.isDown(key2)
end

-- updates variables which depend on other variables
-- necessary after variable changes
function updateVariables()
  mask_height = mask_font:getHeight() +
                math.floor(mask_font:getHeight() / 3)
                                                 -- height of the mask
  text_x = mask_x                                -- x position of mask text
  text_y = mask_y                                -- y position of mask text 

  -- set hud text
  --[[ Hud Preview:
    +/-             Change Text Size
    +/- and Shift   Change Left Margin
    +/- and Alt     Change Right Margin
    Cursor          Move in screen jumps
    Cursor and Alt  Move in pixels
    Space           Swap Colors

    Font size is    14
    Transparent is  Black
    Visible is      White
    Mask width is   2000
    Mask height is  60
    
    F1              Toggle Menu
    F2              Restart
    Escape          Exit
  --]]
  hud_text   = "+/-\n" ..
               "+/- and Shift\n" ..
               "+/- and Alt\n" ..
               "Cursor\n" ..
               "Cursor and Alt\n" ..
               "Space\n" ..
               "\n" ..
               "Font Size\n" ..
               "Transparent\n" ..
               "Visible\n" ..
               "Mask Position\n" ..
               "Mask Width\n" ..
               "Mask Height\n" ..
               "Left Margin\n" ..
               "Right Margin\n" ..
               "\n" ..
               "F1\n" .. 
               "F2\n" ..
               "Escape\n" ..
               "\n\n\n" ..
               error_value
  hud_values = "Change Text Size\n" ..
               "Change Left Margin\n" ..
               "Change Right Margin\n" ..
               "Move in Screen Jumps\n" ..
               "Move in Pixels\n" ..
               "Invert Colors\n" ..
               "\n" ..
               mask_font_size .. "\n" ..
               transparent_color_info .. "\n" ..
               visible_color_info .. "\n" ..
               mask_x .. ", " .. mask_y .. "\n" ..
               mask_width .. "\n" ..
               mask_height .. "\n" ..
               left_margin .. "\n" ..
               right_margin .. "\n" ..
               "\n" ..
               "Toggle Help\n" ..
               "Restart\n" ..
               "Exit\n"
  collectgarbage("collect")
end

-- update what needs to be updated
function update(dt)
  -- holdable keys
  if areDown(love.key_lshift, love.key_lshift) then
  -- Shift is down
    if areDown(love.key_plus, love.key_kp_plus) then
    -- Plus is down
      left_margin = left_margin + 1
      love.timer.sleep(lag)
    elseif areDown(love.key_minus, love.key_kp_minus) then
    -- Minus is down
      left_margin = left_margin - 1
      love.timer.sleep(lag)
    end
    updateVariables()           -- aply changes
  elseif areDown(love.key_lalt, love.key_ralt) then
  -- Alt is down
    if areDown(love.key_plus, love.key_kp_plus) then
    -- Plus is down
      right_margin = right_margin + 1
      love.timer.sleep(lag)
    elseif areDown(love.key_minus, love.key_kp_minus) then
    -- Minus is down
      right_margin = right_margin - 1
      love.timer.sleep(lag)
    else
    -- Plus nor Minus are down
      -- move in pixels
      if love.keyboard.isDown(love.key_up) then
        -- move mask up
        mask_y = mask_y - 1
        love.timer.sleep(lag)
      elseif love.keyboard.isDown(love.key_down) then
        -- move mask down
        mask_y = mask_y + 1
        love.timer.sleep(lag)
      elseif love.keyboard.isDown(love.key_left) then
        -- move mask left
        mask_x = mask_x - 1
        love.timer.sleep(lag)
      elseif love.keyboard.isDown(love.key_right) then
        -- move mask down
        mask_x = mask_x + 1
        love.timer.sleep(lag)
      end
    end
    updateVariables()           -- aply changes
  else
  -- Shift nor Alt are down  
    if areDown(love.key_plus, love.key_kp_plus) then
    -- Plus is down
      -- incrase text size
      mask_font_size = mask_font_size + 1
      mask_font = nil
      collectgarbage("collect") -- free no longer used memory
      mask_font = love.graphics.newFont(mask_font_path, mask_font_size)
      love.timer.sleep(lag)
      updateVariables()         -- aply changes
--      collectgarbage("collect") 
    elseif areDown(love.key_minus, love.key_kp_minus) then
    -- Minus is down
      -- decrase text size
      mask_font_size = mask_font_size - 1
      mask_font = nil
      collectgarbage("collect") -- free no longer used memory
      mask_font = love.graphics.newFont(mask_font_path, mask_font_size)
      love.timer.sleep(lag)
      updateVariables()         -- aply changes
--      collectgarbage("collect")
    end
  end
end

-- draw things on screen
function draw()
  -- count mask
  distance = separator_width
  for i = 1, mask_characters:len() do
    char       = mask_characters:sub(i, i)
    char_width = mask_font:getWidth(char)
    distance   = distance + left_margin + char_width + right_margin +
                 separator_width
  end
  mask_width = distance
  
  -- draw mask
  love.graphics.setColor(transparent_color) -- set mask background color
  love.graphics.rectangle(love.draw_fill, mask_x, mask_y,
                          mask_width, mask_height)
                            
  -- draw mask foreground text
  love.graphics.setColor(visible_color)     -- set mask foreground color
  love.graphics.setFont(mask_font)          -- set mask font color
  
  distance = separator_width
  
  for i = 1, mask_characters:len() do
    char       = mask_characters:sub(i, i)
    char_width = mask_font:getWidth(char)
    distance   = distance + left_margin + char_width + right_margin +
                 separator_width
    love.graphics.draw(char, text_x + distance - char_width -
                       right_margin - separator_width, text_y +
                       mask_font:getHeight())
    updateVariables()
  end
  
  -- draw separators
  love.graphics.setLine(1, love.line_rough) -- set line width and type
  love.graphics.setColor(separator_color)   -- set text separators color
  
  distance = 0
  
  for i = 1, mask_characters:len() +1 do
    char       = mask_characters:sub(i, i)
    char_width = mask_font:getWidth(char)
    distance   = distance + left_margin + char_width + right_margin +
                 separator_width
    love.graphics.rectangle(love.draw_fill, text_x + distance -
                            left_margin - char_width - right_margin -
                            separator_width, mask_y, separator_width,
                            mask_height)
  end
  
  -- draw border
  love.graphics.setLine(2, love.line_rough)
  love.graphics.setColor(border_color)
  love.graphics.rectangle(love.draw_line, 1, 1, window_width -1,
                          window_height -1)
  -- draw HUD
  if show_hud then drawHud() end        -- draw hud?
end

function keypressed(key)
  if not areDown(love.key_lalt, love.key_ralt) then
  -- Alt is down
    -- move in screenjumps
    if key == love.key_up then
    -- Up was pressd
      -- move mask up
      mask_y = mask_y - (window_height - 3) -- 3 is border pixels correction
    elseif key == love.key_down then
    -- Down was pressed
      -- move mask down
      mask_y = mask_y + (window_height - 3) -- 3 is border pixels correction
    elseif key == love.key_left then
    -- Left was pressed
      -- move mask left
      mask_x = mask_x - (window_width  - 3) -- 3 is border pixels correction
    elseif key == love.key_right then
    -- Right was pressed
      -- move mask down
      mask_x = mask_x + (window_width  - 3) -- 3 is border pixels correction
    end
  end
  
  if key == love.key_space then
  -- Space was pressed
    -- invert colors
    stack = visible_color               -- :-)
    visible_color = transparent_color   -- :-)
    transparent_color = stack           -- :-)
    -- give hud the information
    if transparent_color == black then
      transparent_color_info = "Black"
      visible_color_info = "White"
    else
      transparent_color_info = "White"
      visible_color_info = "Black"
    end
  elseif key == love.key_f1 then
  -- F1 was pressed
    -- toggle show/hide menu
    show_hud = not show_hud
  elseif key == love.key_f2 then
  -- F2 was pressed
    -- restart
    love.system.restart()
  elseif key == love.key_escape then
  -- Escape was pressed
    -- exit
    love.system.exit()
  end
  
  updateVariables() -- aply changes
end

-- TODO: improve Invert Colors
